package duotai;

import com.sun.media.jfxmediaimpl.HostUtils;
import javafx.scene.AmbientLight;
import sun.awt.HeadlessToolkit;

/**
 * @User: vitobo
 * @Date: 2024-05-23
 * @Description:
 *
 *  去完成某个行为，当不同的对象去完成时会产生出不同 的状态
 *
 *  多态的实现条件:
 *      1. 必须在继承体系下
 *      2. 子类必须要对父类中方法进行重写
 *      3. 通过父类的引用调用重写的方法
 *
 *
 *  重写和重载区别?
 *      重写是子类对父类非静态、非private修饰，非final修饰，非构造方法等的实现过程
 * 进行重新编写, 返回值和形参都不能改变。
 *      方法重载是一个类的多态性表现
 *      方法重写是子类与父类的一种多态性表现
 *
 *
 *  向上转型和向下转型
 *      向上转型: 是创建一个子类对象，将其当成父类对象来使用
 *      使用场景: 直接赋值, 方法传参, 方法返回
 *
 *      向下转型:将一个子类对象经过向上转型之后当成父类方法使用，再无法调用子类的方法，但有时候可能需要调用子类特有的
 * 方法，此时：将父类引用再还原为子类对象即可，即向下转换。
 *
 *
 * 避免在构造方法中调用重写的方法!!!
 *
 */





class Animal{
    String name;
    int age;

    public Animal(String name, int age){
        this.name = name;
        this.age  = age;
    }

    public void eat(){
        System.out.println(name + "吃饭饭");
    }
}

class Cat extends Animal{
    public Cat(String name, int age){
        super(name, age);
    }

    @Override
    public void eat(){
        System.out.println(name + "吃小鱼");
    }

    public void mew(){
        System.out.println("抓老鼠");
    }
}

class Dog extends Animal{
    public Dog(String name, int age){
        super(name, age);
    }

    @Override
    public void eat(){
        System.out.println(name + "吃骨头");
    }

    public void bark(){
        System.out.println("汪汪叫");
    }
}


public class Test {

    // 向下转型
    public static void main(String[] args) {
        Cat cat = new Cat("花花", 2);
        Dog dog = new Dog("黑子", 2);

        // 向上转型
        Animal animal = cat;
        animal.eat();

        animal = dog;
        animal.eat();

        if(animal instanceof Cat){
            cat = (Cat)animal;
            cat.mew();
        }

        if(animal instanceof Dog){
            dog = (Dog)animal;
            dog.bark();
        }


    }



    // 向上转型:
    // 2.方法传参: 形参为父类型引用,可以接受任意子类的对象
    public static void eatFood(Animal a){
        a.eat();
    }

    // 3.作返回值: 返回任意子类对象
    public static Animal buyAnimal(String val){
        if(val == "狗"){
            return new Dog("狗狗", 1);
        }else if(val == "猫"){
            return new Cat("猫猫", 2);
        }else{
            return null;
        }
    }

    public static void main2(String[] args) {
        // 1.直接赋值, 子类对象赋值给父类对象
        Animal cat = new Cat("小黄", 3);

        Dog dog = new Dog("黑子", 2);

        eatFood(cat);
        Animal animal = buyAnimal("狗");
        animal.eat();

        animal = buyAnimal("猫");
        animal.eat();
    }



    // 在eat方法当中, a引用, 引用的子类对象不一样, 调用方法表现出来的行为不一样,
    // 把这种思想就叫做多态
    public static void eat(Animal a){
        a.eat();
    }

    public static void main1(String[] args) {
        Cat cat = new Cat("咪咪", 2);
        Dog dog = new Dog("黑子", 1);

        eat(cat);
        eat(dog);
    }

}
